/*
 * kdogs - Kick dogs, a lightweight watchdog kicker
 *
 * Copyright (C) 2007 Instituto Nokia de Tecnologia
 *
 * Author: Osvaldo Santana Neto <osvaldo.neto@openbossa.org>
 *         Abner Silva <abner.silva@openbossa.org>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>

#include "kdogsd.h"
#include "kdogs_ioctl.h"

int
_ioctl_init_wdt(kdogs_wdt *wdt)
{
    wdt->fd = open(wdt->path, O_WRONLY);
    if (wdt->fd < 0) {
        errmsg("error opening watchdog %s (%s).\n", wdt->path, strerror(errno));
        return -1;
    }
    return 0;
}

int
_ioctl_close_wdt(kdogs_wdt *wdt)
{
    if (close(wdt->fd)) {
        errmsg("error closing watchdog %s (%s).\n", wdt->path, strerror(errno));
        return -1;
    }
    return 0;
}

int
_ioctl_kick(kdogs_wdt *wdt)
{
    int dummy;

    if (!wdt->fd || ioctl(wdt->fd, WDIOC_KEEPALIVE, &dummy) < 0) {
        errmsg("error kicking watchdog %s (%s).\n", wdt->path, strerror(errno));
        return -1;
    }

    return 0;
}

int
_ioctl_get_timeout(kdogs_wdt *wdt)
{
    if (wdt->timeout <= 0) {
        int timeout;
        if (!wdt->fd || ioctl(wdt->fd, WDIOC_GETTIMEOUT, &timeout) < 0) {
            errmsg("error getting timeout in %s (%s).\n", wdt->path, strerror(errno));
            return -1;
        }

        wdt->timeout = timeout;
    }

    return wdt->timeout;
}

int
_ioctl_set_timeout(kdogs_wdt *wdt, int timeout)
{
    int new_timeout = timeout;

    if (!wdt->fd || ioctl(wdt->fd, WDIOC_SETTIMEOUT, &new_timeout) < 0) {
        errmsg("error setting timeout in %s (%s).\n", wdt->path, strerror(errno));
        return -1;
    }

    return new_timeout;
}

int
_ioctl_get_counter(kdogs_wdt *wdt)
{

#ifdef WDIOC_GETTIMELEFT
    int counter;

    if (!wdt->fd || ioctl(wdt->fd, WDIOC_GETTIMELEFT, &counter) < 0) {
        errmsg("error getting counter in %s (%s).\n", wdt->path, strerror(errno));
        return -1;
    }

    return counter;
#else
    return -1;
#endif

}

